package com.sencorsta.ids.pos;

import com.sencorsta.ids.core.log.Out;
import com.sencorsta.utils.date.DateUtil;

import java.util.Arrays;

import static com.sencorsta.ids.pos.DesUtil.*;
import static java.lang.System.arraycopy;

public class ICe8583Ans extends Easy8583Ans {

    private static final String TAG = " My8583Ans";

    //通信涉及到的一些参数,内部使用
    private static long commSn = 1; //通讯流水号
    private static byte[] licenceNum = {0x33, 0x30, 0x36, 0x30};//入网许可证编号

    private String upBinNumber;  //银行卡卡号
    private String cardSnNumber; //持卡序号
    private String cardValiteDate; //卡有效期
    private String field35Data; //二磁道数据

    //需要外部设置的参数有：商户号，终端号，主秘钥，TPDU(以下的为默认值，并提供set和get方法)
    //需要持久化存储这些参数，每次使用时加载
    private static String manNum = "952718152032495"; //商户号
    private static String posNum = "00000001"; //终端号
    private static String mainKey = "31393532373138313532303332343935"; //主秘钥
    private static String TPDU = "6002010000";
    private static byte[] piciNum = new byte[]{0x00,0x00,0x01};//批次号
    private static long posSn = 127; //终端交易流水,每笔交易加一

    public ICe8583Ans() {

        //通过子类修改父类的配置
        pack.tpdu = hexStringToBytes(TPDU);
        upBinNumber = "";
        cardSnNumber = "";
        cardValiteDate = "";
        field35Data = "";
    }

    /**
     * 签到报文组帧
     *
     * @param field
     * @param tx
     */
    public void frame8583QD(__8583Fields[] field, Pack tx) {

        init8583Fields(fieldsSend);
        //消息类型
        tx.msgType[0] = 0x08;
        tx.msgType[1] = 0x00;
        //11域，受卡方系统跟踪号BCD 通讯流水
        field[10].ishave = 1;
        field[10].len = 3;
        String tmp = String.format("%06d", commSn);
        field[10].data = hexStringToBytes(tmp);
        //41域，终端号
        field[40].ishave = 1;
        field[40].len = 8;
        field[40].data = posNum.getBytes();
        //42域，商户号
        field[41].ishave = 1;
        field[41].len = 15;
        field[41].data = manNum.getBytes();
        //60域
        field[59].ishave = 1;
        field[59].len = 0x11;
        field[59].data = new byte[6];
        field[59].data[0] = 0x00;
        arraycopy(piciNum, 0, field[59].data, 1, 3);
        field[59].data[4] = 0x00;
        field[59].data[5] = 0x30;
        //62域
//        field[61].ishave = 1;
//        field[61].len = 0x25;
//        field[61].data = new byte[25];
//        String str = "Sequence No12";
//        arraycopy(str.getBytes(), 0, field[61].data, 0, 13);
//        arraycopy(licenceNum, 0, field[61].data, 13, 4);
//        arraycopy(posNum.getBytes(), 0, field[61].data, 17, 8);
        //63域
        field[62].ishave = 1;
        field[62].len = 0x03;
        field[62].data = new byte[3];
        field[62].data[0] = 0x30;
        field[62].data[1] = 0x31;
        field[62].data[2] = 0x20;
        /*报文组帧，自动组织这些域到Pack的TxBuffer中*/
        pack8583Fields(field, tx);
        commSn++; //通讯流水每次加一
    }

    /**
     * 8583签到的响应报文解析
     *
     * @param rxbuf
     * @param rxlen
     * @return 0，成功 非0，失败
     */
    public int ans8583QD(byte[] rxbuf, int rxlen) {

        int ret = 0;
        ret = ans8583Fields(rxbuf, rxlen, fieldsRecv);
        if (ret != 0) {
            //Log.d(TAG,"解析失败！");
            System.out.println("<-Er 解析失败！");
            return ret;
        }
        //Log.d(TAG,"解析成功！");
        System.out.println("->ok 解析成功！");
        //消息类型判断
        if ((pack.msgType[0] != 0x08) || (pack.msgType[1] != 0x10)) {
            Out.debug(TAG,"消息类型错！");
            return 2;
        }
        //应答码判断
        if ((fieldsRecv[38].data[0] != 0x30) || (fieldsRecv[38].data[1] != 0x30)) {
            Out.debug(TAG,"应答码不正确！");
            Out.debug(TAG,String.format("应答码:%02x%02x",fieldsRecv[38].data[0],fieldsRecv[38].data[1]));
            return 3;
        }
        //跟踪号比较
        if (!Arrays.equals(fieldsSend[10].data, fieldsRecv[10].data)) {
            //return 4;
        }
        //终端号比较
        if (!Arrays.equals(fieldsSend[40].data, fieldsRecv[40].data)) {
            //return 5;
        }
        //商户号比较
        if (!Arrays.equals(fieldsSend[41].data, fieldsRecv[41].data)) {
            //return 6;
        }

        //暴力尝试
        {
            System.out.println("--------------------------暴力尝试-----------------------------------");
            String keys="0128bf8d8e5f090a777cca87131fbfac0a000b834cce4390b2a06d1eb9358970bc403ed3dd7baac9460d644c56fdfbc1f89fcac1e20f93130a3c7243393607a51026f0f301d761d61aabd81e1cb9178db6819df65c61d41a280722e6ebbb9e8003ed74437034d1f035b0b30852af01d6c11835b405b1837b96a8ec03031bbb795d27";
            int lenth=mainKey.length();
            for (int i = 0; i <keys.length()-lenth ; i++) {
                String subStr=keys.substring(i,i+lenth);
                System.out.println("subStr："+subStr);

                //3DES解密PIN KEY
                byte[] data = new byte[16];
                arraycopy(fieldsRecv[61].data, 0, data, 0, 16);
                byte[] pinkey = DES_decrypt_3(data, hexStringToBytes(subStr));
                //解密后的结果对8Byte全0做3DES加密运算
                System.out.println("pinkey:" + bytesToHexString(pinkey));
                byte[] tmp = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
                byte[] out = DES_encrypt_3(tmp, pinkey);
                //对比pincheck是否一致
                byte[] check = new byte[4];
                byte[] pincheck = new byte[4];
                arraycopy(out, 0, check, 0, 4);
                arraycopy(fieldsRecv[61].data, 16, pincheck, 0, 4);
                if (!Arrays.equals(check, pincheck)) {
                    System.out.println("<-Er PIK错误");
                    //return 7;
                } else {
                    System.out.println("subStr："+subStr);
                    System.out.println("<-ok PIK正确！！！！！！！！！！！！！！！！！！！！！！！！");
                }

            }
            System.out.println("--------------------------暴力尝试-----------------------------------");

        }


        //3DES解密PIN KEY
        byte[] data = new byte[16];
        arraycopy(fieldsRecv[61].data, 0, data, 0, 16);
        byte[] pinkey = DES_decrypt_3(data, hexStringToBytes(mainKey));
        //解密后的结果对8Byte全0做3DES加密运算
        System.out.println("pinkey:" + bytesToHexString(pinkey));
        byte[] tmp = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        byte[] out = DES_encrypt_3(tmp, pinkey);
        //对比pincheck是否一致
        byte[] check = new byte[4];
        byte[] pincheck = new byte[4];
        arraycopy(out, 0, check, 0, 4);
        arraycopy(fieldsRecv[61].data, 16, pincheck, 0, 4);
        if (!Arrays.equals(check, pincheck)) {
            System.out.println("<-Er PIK错误");
            //return 7;
        } else {
            System.out.println("<-ok PIK正确");
        }
        //3DES解密MAC KEY
        arraycopy(fieldsRecv[61].data, 20, data, 0, 16);
        //setMacKey(bytesToHexString(data));
        byte[] mackey = DES_decrypt_3(data, hexStringToBytes(mainKey));
        //解密后的结果对8Byte全0做DES加密运算
        System.out.println("mackey:" + bytesToHexString(mackey));
        out = DES_encrypt(tmp, mackey);

        byte[] maccheck = new byte[4];
        arraycopy(out, 0, check, 0, 4);
        arraycopy(fieldsRecv[61].data, 36, maccheck, 0, 4);
        if (!Arrays.equals(check, maccheck)) {
            System.out.println("<-Er MAC错误");
            //return 8;
        } else {
            System.out.println("<-ok MAC正确");
        }
        //保存macKey
        Out.debug("保存macKey");
        setMacKey(bytesToHexString(mackey));

        //保存批次号
        arraycopy(fieldsRecv[59].data, 1, piciNum, 0, 3);
        //签到成功
        return 0;
    }

    /**
     * 银联二维码组包
     *
     * @param field
     * @param tx
     */
    public void frame8583Qrcode(String qrcode, int money, __8583Fields[] field, Pack tx) {

        if (qrcode.length() != 19) {
            return;
        }
        init8583Fields(fieldsSend);
        //消息类型
        tx.msgType[0] = 0x02;
        tx.msgType[1] = 0x00;
        //3域 交易处理码
        field[2].ishave = 1;
        field[2].len = 3;
        field[2].data = new byte[]{0x00, 0x00, 0x00};
        //4域 交易金额
        field[3].ishave = 1;
        field[3].len = 6;
        String strtmp = String.format("%012d", money);
        field[3].data = hexStringToBytes(strtmp);

        //11域，pos终端交易流水
        field[10].ishave = 1;
        field[10].len = 3;
        String tmp = String.format("%06d", posSn);
        field[10].data = hexStringToBytes(tmp);
        //22域
        field[21].ishave = 1;
        field[21].len = 2;
        field[21].data = new byte[]{0x03, 0x20};
        // 25域
        field[24].ishave = 1;
        field[24].len = 1;
        field[24].data = new byte[]{0x00};
        //
        //41域，终端号
        field[40].ishave = 1;
        field[40].len = 8;
        field[40].data = posNum.getBytes();
        //42域，商户号
        field[41].ishave = 1;
        field[41].len = 15;
        field[41].data = manNum.getBytes();

        //49域 交易货币代码
        field[48].ishave = 1;
        field[48].len = 3;
        field[48].data = new byte[]{0x31, 0x35, 0x36};

        //59域，扫码的数据
        field[58].ishave = 1;
        field[58].len = 0x24;
        field[58].data = new byte[24];
        field[58].data[0] = 'A'; //TAG+Len(019)
        field[58].data[1] = '3';
        field[58].data[2] = '0';
        field[58].data[3] = '1';
        field[58].data[4] = '9';
        arraycopy(qrcode.getBytes(), 0, field[58].data, 5, 19);

        //60域
        field[59].ishave = 1;
        field[59].len = 0x13;
        field[59].data = new byte[7];
        field[59].data[0] = 0x22;
        arraycopy(piciNum, 0, field[59].data, 1, 3);
        field[59].data[4] = 0x00;
        field[59].data[5] = 0x06;
        field[59].data[6] = 0x00;
        //MAC，64域
        field[63].ishave = 1;
        field[63].len = 0x08;
        field[63].data = new byte[8];
        //这个域要求填MAC，只需按这样填，MAC的计算在pack8583Fields自动完成了
        /*报文组帧，自动组织这些域到Pack的TxBuffer中*/
        pack8583Fields(field, tx);
        commSn++; //通讯流水每次加一
    }

    public int ans8583Qrcode(byte[] rxbuf, int rxlen) {

        int ret = 0;
        ret = ans8583Fields(rxbuf, rxlen, fieldsRecv);
        if (ret != 0) {
            //Log.d(TAG,"解析失败！");
            System.out.println("<-Er 解析失败！");
            return ret;
        }
        //Log.d(TAG,"解析成功！");
        System.out.println("->ok 解析成功！");
        //消息类型判断
        if ((pack.msgType[0] != 0x02) || (pack.msgType[1] != 0x10)) {
            //Log.d(TAG,"消息类型错！");
            System.out.println("消息类型错！");
            return 2;
        }
        //应答码判断
        if ((fieldsRecv[38].data[0] != 0x30) || (fieldsRecv[38].data[1] != 0x30)) {
            Out.info(TAG, "应答码不正确！");
            Out.info(TAG, String.format("应答码:%02x%02x", fieldsRecv[38].data[0], fieldsRecv[38].data[1]));
            return 3;
        }
        //跟踪号比较
        if (!Arrays.equals(fieldsSend[10].data, fieldsRecv[10].data)) {
            return 4;
        }
        //终端号比较
        if (!Arrays.equals(fieldsSend[40].data, fieldsRecv[40].data)) {
            return 5;
        }
        //商户号比较
        if (!Arrays.equals(fieldsSend[41].data, fieldsRecv[41].data)) {
            return 6;
        }
        //成功
        return 0;
    }

    /**
     * 从传入参数的TLV格式的数据源中解析出55域需要的数据
     *
     * @param src   需要解析的数据源(TLV格式)
     * @param money 交易金额
     * @param date  交易日期 格式如:"180707",必须跟卡指令中传的金额和日期一致
     * @return
     */
    byte[] getFieldData55(byte[] src, int money, String date) {

        return null;

    }

    int intToHex(int d) {
        int out = 0;
        out = ((d / 10) << 4);
        out |= (d % 10);
        return out;
    }

    /**
     * 银联小额双免组包
     *
     * @param carddata 卡上数据
     * @param money    交易金额(单位分)
     * @param date     日期（长度为6） 格式如：180707
     * @param field
     * @param tx
     */
    public void frameShuangMian(byte[] carddata, int money, String date, __8583Fields[] field, Pack tx) {

        init8583Fields(fieldsSend);
        if (date.length() != 6) {
            return;
        }
        byte[] field55 = getFieldData55(carddata, money, date);
        if (upBinNumber.equals("") || field35Data.equals("")) {
            return;
        }
        //消息类型
        tx.msgType[0] = 0x02;
        tx.msgType[1] = 0x00;
        //2域 银行卡号
        field[1].ishave = 1;
        String strtemp = String.format("%02d", upBinNumber.length());
        byte[] tmp = hexStringToBytes(strtemp);
        field[1].len = tmp[0];
        strtemp = upBinNumber;
        if (upBinNumber.length() % 2 != 0) {
            strtemp += "0";
        }
        field[1].data = hexStringToBytes(strtemp);

        //3域 交易处理码
        field[2].ishave = 1;
        field[2].len = 3;
        field[2].data = new byte[]{0x00, 0x00, 0x00};
        //4域 交易金额
        field[3].ishave = 1;
        field[3].len = 6;
        String strtmp = String.format("%012d", money);
        field[3].data = hexStringToBytes(strtmp);

        //11域，pos终端交易流水
        field[10].ishave = 1;
        field[10].len = 3;
        String tmp1 = String.format("%06d", posSn);
        field[10].data = hexStringToBytes(tmp1);

        //14域，卡有效期
        if (cardValiteDate.equals("")) {
        } else {
            field[13].ishave = 1;
            field[13].len = 2;
            field[13].data = hexStringToBytes(cardValiteDate);
        }
        //22域
        field[21].ishave = 1;
        field[21].len = 2;
        field[21].data = new byte[]{0x07, 0x20};

        //23域卡片序列号
        if (cardSnNumber.equals("")) {
            field[22].ishave = 1;
            field[22].len = 2;
            field[22].data = new byte[]{0x00, 0x00};
        } else {
            field[22].ishave = 1;
            field[22].len = 2;
            field[22].data = new byte[]{0x00, 0x00};
            if (cardSnNumber.equals("01")) {
                field[22].data[1] = 0x01;
            }
        }
        // 25域
        field[24].ishave = 1;
        field[24].len = 1;
        field[24].data = new byte[]{0x00};
        //35域，二磁道数据
        field[34].ishave = 1;
        int tmplen = field35Data.length();
        if (field35Data.charAt(tmplen - 1) == 'f') {
            tmplen = intToHex(tmplen);//转为HEX
            field[34].len = tmplen - 1;
        } else {
            tmplen = intToHex(tmplen);//转为HEX
            field[34].len = tmplen;
        }
        field[34].data = hexStringToBytes(field35Data);

        //41域，终端号
        field[40].ishave = 1;
        field[40].len = 8;
        field[40].data = posNum.getBytes();
        //42域，商户号
        field[41].ishave = 1;
        field[41].len = 15;
        field[41].data = manNum.getBytes();

        //49域 交易货币代码
        field[48].ishave = 1;
        field[48].len = 3;
        field[48].data = new byte[]{0x31, 0x35, 0x36};

        //55域，卡上TLV数据组包
        field[54].ishave = 1;
        //field[54].len = 3;
        String tmplen1 = String.format("%04d", field55.length);
        byte[] tmpby = hexStringToBytes(tmplen1);
        field[54].len = (((tmpby[0] & 0xff) << 8) | (tmpby[1] & 0xff));
        field[54].data = field55.clone();

        //60域
        field[59].ishave = 1;
        field[59].len = 0x13;
        field[59].data = new byte[7];
        field[59].data[0] = 0x22;
        arraycopy(piciNum, 0, field[59].data, 1, 3);
        field[59].data[4] = 0x00;
        field[59].data[5] = 0x06;
        field[59].data[6] = 0x00;
        //MAC，64域
        field[63].ishave = 1;
        field[63].len = 0x08;
        field[63].data = new byte[8];
        //这个域要求填MAC，只需按这样填，MAC的计算在pack8583Fields自动完成了
        /*报文组帧，自动组织这些域到Pack的TxBuffer中*/
        pack8583Fields(field, tx);
        commSn++; //通讯流水每次加一
    }

    /**
     * 双免收到的应答报文解析
     *
     * @param rxbuf
     * @param rxlen
     * @return
     */
    public int ansShuangMian(byte[] rxbuf, int rxlen) {

        int ret = 0;
        ret = ans8583Fields(rxbuf, rxlen, fieldsRecv);
        if (ret != 0) {
            //Log.d(TAG,"解析失败！");
            System.out.println("<-Er 解析失败！");
            return ret;
        }
        //Log.d(TAG,"解析成功！");
        System.out.println("->ok 解析成功！");
        //消息类型判断
        if ((pack.msgType[0] != 0x02) || (pack.msgType[1] != 0x10)) {
            //Log.d(TAG,"消息类型错！");
            System.out.println("消息类型错！");
            return 2;
        }
        //应答码判断
        if ((fieldsRecv[38].data[0] != 0x30) || (fieldsRecv[38].data[1] != 0x30)) {
            Out.info(TAG, "应答码不正确！");
            Out.info(TAG, String.format("应答码:%02x%02x", fieldsRecv[38].data[0], fieldsRecv[38].data[1]));
            return 3;
        }
        //跟踪号比较
        if (!Arrays.equals(fieldsSend[10].data, fieldsRecv[10].data)) {
            return 4;
        }
        //终端号比较
        if (!Arrays.equals(fieldsSend[40].data, fieldsRecv[40].data)) {
            return 5;
        }
        //商户号比较
        if (!Arrays.equals(fieldsSend[41].data, fieldsRecv[41].data)) {
            return 6;
        }
        //成功
        return 0;
    }

    /**
     * 批结算组包，当后台报交易流水重复，响应码94时，批结算后允许交易流水从一开始
     *
     * @param field
     * @param tx
     */
    public void frame8583Batch(__8583Fields[] field, Pack tx) {

        init8583Fields(fieldsSend);
        //消息类型
        tx.msgType[0] = 0x05;
        tx.msgType[1] = 0x00;

        //11域，通信流水
        field[10].ishave = 1;
        field[10].len = 3;
        String tmp = String.format("%06d", commSn);
        field[10].data = hexStringToBytes(tmp);
        //
        //41域，终端号
        field[40].ishave = 1;
        field[40].len = 8;
        field[40].data = posNum.getBytes();
        //42域，商户号
        field[41].ishave = 1;
        field[41].len = 15;
        field[41].data = manNum.getBytes();

        //48域
        field[47].ishave = 1;
        field[47].len = 0x62;
        field[47].data = new byte[31];
        Arrays.fill(field[47].data, (byte) 0);
        //49域 交易货币代码
        field[48].ishave = 1;
        field[48].len = 3;
        field[48].data = new byte[]{0x31, 0x35, 0x36};

        //60域
        field[59].ishave = 1;
        field[59].len = 0x11;
        field[59].data = new byte[6];
        field[59].data[0] = 0x00;
        arraycopy(piciNum, 0, field[59].data, 1, 3);
        field[59].data[4] = 0x20;
        field[59].data[5] = 0x10;

        //63域
        field[62].ishave = 1;
        field[62].len = 0x23;
        field[62].data = new byte[23];
        Arrays.fill(field[62].data, (byte) 'X');
        field[62].data[0] = 0x01;
        field[62].data[1] = 0x01;
        field[62].data[2] = 0x01;
        /*报文组帧，自动组织这些域到Pack的TxBuffer中*/
        pack8583Fields(field, tx);
        commSn++; //通讯流水每次加一
    }

    /**
     * 8583批结算响应报文解析
     *
     * @param rxbuf
     * @param rxlen
     * @return 0，成功 非0，失败
     */
    public int ans8583Batch(byte[] rxbuf, int rxlen) {

        int ret = 0;
        ret = ans8583Fields(rxbuf, rxlen, fieldsRecv);
        if (ret != 0) {
            //Log.d(TAG,"解析失败！");
            System.out.println("<-Er 解析失败！");
            return ret;
        }
        //Log.d(TAG,"解析成功！");
        System.out.println("->ok 解析成功！");
        //消息类型判断
        if ((pack.msgType[0] != 0x05) || (pack.msgType[1] != 0x10)) {
            //Log.d(TAG,"消息类型错！");
            return 2;
        }

        //跟踪号比较
        if (!Arrays.equals(fieldsSend[10].data, fieldsRecv[10].data)) {
            return 4;
        }
        //终端号比较
        if (!Arrays.equals(fieldsSend[40].data, fieldsRecv[40].data)) {
            return 5;
        }
        //商户号比较
        if (!Arrays.equals(fieldsSend[41].data, fieldsRecv[41].data)) {
            return 6;
        }
        //批结算成功
        return 0;
    }

    /**
     * 批结算结束报文组帧
     *
     * @param field
     * @param tx
     */
    public void frame8583BatchOver(__8583Fields[] field, Pack tx) {

        init8583Fields(fieldsSend);
        //消息类型
        tx.msgType[0] = 0x03;
        tx.msgType[1] = 0x20;

        //11域，通信流水
        field[10].ishave = 1;
        field[10].len = 3;
        String tmp = String.format("%06d", commSn);
        field[10].data = hexStringToBytes(tmp);
        //
        //41域，终端号
        field[40].ishave = 1;
        field[40].len = 8;
        field[40].data = posNum.getBytes();
        //42域，商户号
        field[41].ishave = 1;
        field[41].len = 15;
        field[41].data = manNum.getBytes();

        //48域
        field[47].ishave = 1;
        field[47].len = 0x04;
        field[47].data = new byte[2];
        Arrays.fill(field[47].data, (byte) 0);

        //60域
        field[59].ishave = 1;
        field[59].len = 0x11;
        field[59].data = new byte[6];
        field[59].data[0] = 0x00;
        arraycopy(piciNum, 0, field[59].data, 1, 3);
        field[59].data[4] = 0x20;
        field[59].data[5] = 0x70;

        /*报文组帧，自动组织这些域到Pack的TxBuffer中*/
        pack8583Fields(field, tx);
        commSn++; //通讯流水每次加一
    }

    /**
     * 批结结束应答报文解析
     *
     * @param rxbuf
     * @param rxlen
     * @return
     */
    public int ans8583BatchOver(byte[] rxbuf, int rxlen) {

        int ret = 0;
        ret = ans8583Fields(rxbuf, rxlen, fieldsRecv);
        if (ret != 0) {
            //Log.d(TAG,"解析失败！");
            System.out.println("<-Er 解析失败！");
            return ret;
        }
        //Log.d(TAG,"解析成功！");
        System.out.println("->ok 解析成功！");
        //消息类型判断
        if ((pack.msgType[0] != 0x03) || (pack.msgType[1] != 0x30)) {
            Out.info(TAG, "消息类型错！");
            //System.out.println("消息类型错！");
            return 2;
        }
        //应答码判断
        if ((fieldsRecv[38].data[0] != 0x30) || (fieldsRecv[38].data[1] != 0x30)) {
            Out.info(TAG, "应答码不正确！");
            Out.info(TAG, String.format("应答码:%02x%02x", fieldsRecv[38].data[0], fieldsRecv[38].data[1]));
            return 3;
        }
        //跟踪号比较
        if (!Arrays.equals(fieldsSend[10].data, fieldsRecv[10].data)) {
            return 4;
        }
        //终端号比较
        if (!Arrays.equals(fieldsSend[40].data, fieldsRecv[40].data)) {
            return 5;
        }
        //商户号比较
        if (!Arrays.equals(fieldsSend[41].data, fieldsRecv[41].data)) {
            return 6;
        }
        //成功
        return 0;
    }

    /**
     * 微信二维码组包
     *
     * @param time
     * @param date
     * @param field
     * @param tx
     */
    public void frame8583QRWX(int money, String time, String date, __8583Fields[] field, Pack tx) {
        init8583Fields(fieldsSend);
        //消息类型
        tx.msgType[0] = 0x02;
        tx.msgType[1] = 0x00;
        //3域 交易处理码
        field[2].ishave = 1;
        field[2].len = 3;
        field[2].data = new byte[]{0x00, 0x00, 0x00};
        //4域 交易金额
        field[3].ishave = 1;
        field[3].len = 6;
        String strtmp = String.format("%012d", money);
        field[3].data = hexStringToBytes(strtmp);

        //11域，pos终端交易流水
        field[10].ishave = 1;
        field[10].len = 3;
        String tmp = String.format("%06d", posSn);
        field[10].data = hexStringToBytes(tmp);
        //22域
        field[21].ishave = 1;
        field[21].len = 2;
        field[21].data = new byte[]{0x03, 0x00};
        // 25域
        field[24].ishave = 1;
        field[24].len = 1;
        field[24].data = new byte[]{(byte) 0x99};
        //
        //41域，终端号
        field[40].ishave = 1;
        field[40].len = 8;
        field[40].data = posNum.getBytes();
        //42域，商户号
        field[41].ishave = 1;
        field[41].len = 15;
        field[41].data = manNum.getBytes();

        //49域 交易货币代码
        field[48].ishave = 1;
        field[48].len = 3;
        field[48].data = new byte[]{0x31, 0x35, 0x36};

        //60域
        field[59].ishave = 1;
        field[59].len = 0x19;
        field[59].data = new byte[10];
        field[59].data[0] = 0x26;
        arraycopy(piciNum, 0, field[59].data, 1, 3);
        field[59].data[4] = 0x00;
        field[59].data[5] = 0x06;
        field[59].data[6] = 0x00;

        //62域
        field[61].ishave = 1;
        field[61].len = 0x40;
        field[61].data = new byte[field[61].len];
        field[61].data[0] = 0x5f;
        field[61].data[1] = 0x01;
        field[61].data[2] = 0x04;
        field[61].data[3] = 0x30;
        field[61].data[4] = 0x30;
        field[61].data[5] = 0x30;
        field[61].data[6] = 0x30;
        field[61].data[7] = 0x5f;
        field[61].data[8] = 0x02;
        field[61].data[9] = 0x08;
        field[61].data[10] = 0x5a;
        field[61].data[11] = 0x53;
        field[61].data[12] = 0x57;
        field[61].data[13] = 0x45;
        field[61].data[14] = 0x43;
        field[61].data[15] = 0x48;
        field[61].data[16] = 0x41;
        field[61].data[17] = 0x54;
        field[61].data[18] = 0x5f;
        field[61].data[19] = 0x03;
        field[61].data[20] = 0x06;
        arraycopy(time.getBytes(), 0, field[61].data, 21, 6);
//        field[61].data[21] = 0x31;
//        field[61].data[22] = 0x39;
//        field[61].data[23] = 0x30;
//        field[61].data[24] = 0x31;
//        field[61].data[25] = 0x34;
//        field[61].data[26] = 0x39;
        field[61].data[27] = 0x5f;
        field[61].data[28] = 0x04;
        field[61].data[29] = 0x06;
        arraycopy(date.getBytes(), 0, field[61].data, 30, 6);
//        field[61].data[30] = 0x31;
//        field[61].data[31] = 0x39;
//        field[61].data[32] = 0x30;
//        field[61].data[33] = 0x38;
//        field[61].data[34] = 0x30;
//        field[61].data[35] = 0x37;
        field[61].data[36] = 0x5C;
        field[61].data[37] = 0x02;
        field[61].data[38] = 0x30;
        field[61].data[39] = 0x33;

        //arraycopy(qrcode.getBytes(),0,field[59].data,5,19);

        //62域
//        field[61].ishave = 1;
//        field[61].len = 0x04;
//        field[61].data = new byte[field[61].len];
//        field[61].data[0] = 0x5C;
//        field[61].data[1] = 0x02;
//        field[61].data[2] = 0x30;
//        field[61].data[3] = 0x33;


//        field[61].ishave = 1;
//        field[61].len = 0x07;
//        field[61].data = new byte[7];
//        field[61].data[0] = 0x22;
//        arraycopy(piciNum,0,field[61].data,1,3);
//        field[61].data[4] = 0x00;
//        field[61].data[5] = 0x06;
//        field[61].data[6] = 0x00;


        //MAC，64域
        field[63].ishave = 1;
        field[63].len = 0x08;
        field[63].data = new byte[8];
        //这个域要求填MAC，只需按这样填，MAC的计算在pack8583Fields自动完成了
        /*报文组帧，自动组织这些域到Pack的TxBuffer中*/
        pack8583Fields(field, tx);
        commSn++; //通讯流水每次加一
    }


    public static void setManNum(String manNum) {
        ICe8583Ans.manNum = manNum;
    }

    public static void setPosNum(String posNum) {
        ICe8583Ans.posNum = posNum;
    }

    public static void setMainKey(String mainKey) {
        ICe8583Ans.mainKey = mainKey;
    }

    public static void setTPDU(String TPDU) {
        ICe8583Ans.TPDU = TPDU;
    }

    public static String getManNum() {
        return manNum;
    }

    public static String getPosNum() {
        return posNum;
    }

    public static String getMainKey() {
        return mainKey;
    }

    public static String getTPDU() {
        return TPDU;
    }

    /**
     * 调用demo
     *
     * @param args
     */
    public static void main(String[] args) {
        ICe8583Ans myans = new ICe8583Ans();
        byte[] send = new byte[myans.pack.txLen];
        System.out.println("->签到包 demo");
        myans.frame8583QD(myans.fieldsSend,myans.pack);
        //打印出待发送的报文
        send = new byte[myans.pack.txLen];
        arraycopy(myans.pack.txBuffer,0,send,0,myans.pack.txLen);
        System.out.println("->send:");
        System.out.println(My8583Ans.bytesToHexString(send));
        System.out.println(myans.pack.toString());
        System.out.println(myans.getFields(myans.fieldsSend));

        //模拟返回
        String recvstr ="008e60000002016002000000000810003800010ac0001400000116065708150848502000353039393537363233363031303030303030303030313935323731383135323033323439350011000000010030006100b3c362bb42334b321a5699c1fe363a9a02526653564176d38176cebe0000000000000000fe25b6c91dd48872559f7d04d270b5303fa9619e24020a24";
        System.out.println("->recv:"+recvstr);
        byte[] recv = My8583Ans.hexStringToBytes(recvstr);
        // mypack.ans8583Fields(bt,bt.length,mypack.fieldsRecv);
        //解析
        System.out.println("开始解析...");
        int ret = myans.ans8583QD(recv,recv.length);

        System.out.println(myans.pack.toString());
        System.out.println(myans.getFields(myans.fieldsRecv));

        if(ret == 0){
            //打印出解析成功的各个域
            System.out.println("签到成功!");
            System.out.println(myans.getFields(myans.fieldsRecv));
        }


//        System.out.println("->微信二维码交易 demo");
//        int  money = 12345; //1分
//        String time= DateUtil.getTime("HHmmss");
//        String date= DateUtil.getTime("yyMMdd");
//        myans.frame8583QRWX(money,time,date,myans.fieldsSend, myans.pack);
//        //打印出待发送的报文
//        send = new byte[myans.pack.txLen];
//        arraycopy(myans.pack.txBuffer, 0, send, 0, myans.pack.txLen);
//        System.out.println("->send:");
//        System.out.println(My8583Ans.bytesToHexString(send));
//        System.out.println(myans.pack.toString());
//        System.out.println(myans.getFields(myans.fieldsSend));
    }
}